Intersections of Adversity & Neurodiversity: Adverse Childhood Experiences’ Association to Mental Health & the Buffering Role of Flourishing
This study extends analyses conducted by Bethell et al. (2023), who explored the role of family resilience and connection in promoting flourishing among U.S. children facing adversity. Our study applies a similar framework but focuses on neurodivergent children, examining how adverse childhood experiences (ACEs) influence mental health outcomes and how flourishing behaviors—such as curiosity, emotional control, and task persistence—may buffer these effects. This study was conducted by the Slopen Laboratory at the Harvard T.H. Chan School of Public Health.
Author: Adrián Medina
Date: October 7, 2024
Project Overview
This repository contains files relevant to a study investigating the relationship between adverse childhood experiences (ACEs) and mental health outcomes in children with neurodevelopmental disorders (NDDs), such as Autism Spectrum Disorder (ASD) and ADHD. The study specifically examines the moderating role of child flourishing behaviors—curiosity in learning, emotional control, and task persistence—on the effects of ACEs on mental health outcomes.
Study Design:
The study utilizes data from the National Survey of Children’s Health (NSCH), focusing on children aged 6-17 with reported neurodevelopmental issues (N = 44,776, MAge = 12.2). This cross-sectional analysis examines ACE exposure and its impact on three primary mental health outcomes: anxiety, depression, and behavioral issues. The moderating role of child flourishing behaviors is assessed using interaction terms in logistic regression models.
Data Collection:
Key variables collected include:
Adverse Childhood Experiences (ACEs): Derived from parent-reported experiences such as exposure to violence, household dysfunction, and discrimination.
Mental Health Outcomes: Parent-reported diagnoses of anxiety, depression, and behavioral problems, confirmed by health care providers or educators.
Child Flourishing Metrics: Based on parent-reported behaviors such as curiosity in learning, emotional control, and task persistence, which were used to develop a Child Flourishing Index (CFI).
Analytic Approach:
The primary analytic approach involved logistic regression models to assess the association between ACEs and mental health outcomes, with interaction terms to explore the moderating effect of child flourishing. Key covariates include age, sex, race/ethnicity, and socioeconomic status.
Goals:
The study aims to:
Examine the dose-response relationship between the number of ACEs and risks of mental health challenges in neurodivergent children.
Identify the protective role of child flourishing behaviors, offering insights into resilience-promoting interventions for this vulnerable population.
Tip
For detailed information on the dataset variables, refer to the NSCH Data Dictionary.
Set up the R environment by configuring the CRAN repository, installing essential packages, setting the base path, and loading the primary dataset into the local environment.
Expand Code
# Set CRAN repository for consistent package installationoptions(repos =c(CRAN ="http://cran.rstudio.com/"))# Install and load the pacman package for efficient package managementif (!require(pacman)) install.packages("pacman")library(pacman)# Use p_load function to install (if necessary) and load packagesp_load(dplyr, tidyr, tidyverse, knitr, ggplot2, Hmisc, broom, stats, kableExtra, webshot2, sjPlot, margins, gtsummary, ggstats, broom.helpers, patchwork, sjlabelled, sjmisc)# Specify the 'base_path' where you can find your data files, ASSUMING they're in the same directory, & set it as WDbase_path <-"~/GitHub/Adversity-Neurodiversity/data_files"setwd(base_path)# Load primary data fileneurodivergent_data <-read_csv("neurodivergent_data.csv")
1
See details under the Data Extraction & Filtering (Archived Code) callout below!
Data Extraction & Filtering (Archived Code)
The file being used for these analyses is a subset of a “master” file, Data2_2016to2022.csv, containing the compiled contents of the data releases from the National Survey on Child Health’s 2016-2022 cycles. The master file is nearly 500 MB (0.5 GB) in size, making it cumbersome to process in real-time. For efficiency and ease of analysis, I am using a smaller subset that contains only the relevant data. This subset was generated using the data extraction and filtering process detailed in the archived code below, in an effort to maintain transparency and ensure reproducibility of the workflow.
Expand Code
# Define the path to the datasetdata_path <-"~/Downloads/Data2_2016to2022.csv"Data2_2016to2022 <-read.csv(data_path)# Select specific variables, create 'neurodivergent' variable, & filter data based on age and neurodivergent statusneurodivergent_data <- Data2_2016to2022 %>%select(year, fpl, fpl_mean, sc_age_years, sc_hispanic_r, sc_race_r, sc_sex, higrade_tvis, k2q35a, k2q35c, k2q38a, k2q38c, k2q30a, k2q30c, k2q36a, k2q36c, k2q60a, k2q60c, k2q37a, k2q37c, downsyn, downsyn_desc, k2q31a, k2q31c, k2q61a, cerpals_desc, k2q33a, k2q33b, k2q33c, k2q32a, k2q32b, k2q32c, k2q34a, k2q34b, k2q34c, ace1, ace3, ace4, ace5, ace6, ace7, ace8, ace9, ace10, ace11, ace12, k6q71_r, k7q85_r, k7q84_r) %>%# Creating 'neurodivergent' variable as NSCH does not explicitly inquire about neurodivergent status.# Using a list of diagnoses provided by NSCH to define neurodivergent individuals.mutate(neurodivergent =if_else(k2q35a ==1| k2q38a ==1| k2q36a ==1| k2q60a ==1| k2q37a ==1| k2q30a ==1| downsyn ==1| k2q31a ==1| k2q61a ==1, 1, 0)) %>%# Filter data to include only individuals aged 6 or above and identified as neurodivergentfilter(sc_age_years >=6, neurodivergent ==1)# Resulting filtered data to be used for further analysiswrite.csv(neurodivergent_data, "neurodivergent_data.csv")
Analytic Data Preparation
Set up recoding of variables by transforming ‘ace1’ into a dichotomous variable, calculating the Childhood Flourishing Index (CFI), and categorizing total ACE counts. Recode education, income, sex, race/ethnicity, and CFI into categorical factors for analysis.
Expand Code
# Recode 'ace1' to dichotomous variable based on analytic specificationsneurodivergent_data$ace1_recode <-ifelse(neurodivergent_data$ace1 %in%c(2, 3, 4), 1, ifelse(neurodivergent_data$ace1 ==1, 0, NA))# Recode ACE counts and calculate Childhood Flourishing Index (CFI)neurodivergent_data <- neurodivergent_data %>%mutate(# Total ACE count for each child excluding missing valuesace_total =rowSums(select(., ace1_recode, ace3:ace12) ==1, na.rm =TRUE),# Categorize total ACEs for further analysisace_counts =cut(ace_total, breaks =c(-1, 0, 1, 3, Inf), labels =c('0', '1', '2-3', '4+'), right =TRUE),ace_counts =factor(ace_counts, levels =c("0", "1", "2-3", "4+")), # Recreate 'ace_counts' factor# Calculate the Childhood Flourishing Index (CFI)CFI =rowSums(select(., k6q71_r, k7q85_r, k7q84_r) ==1, na.rm =TRUE),# Recode CFI into dichotomous variableCFI_dich =case_when( CFI ==3~"Flourishing", CFI %in%0:2~"Not Flourishing",TRUE~NA_character_ ),CFI_dich =factor(CFI_dich, levels =c("Not Flourishing", "Flourishing")) # Recreate 'CFI_dich' factor )# Recode binary outcomes for anxiety, depression, and behavioral issues into factorsneurodivergent_data <- neurodivergent_data %>%mutate(# Recode Anxiety (k2q33b)Anxiety =factor(k2q33b, levels =c(2, 1), labels =c("No", "Yes")),# Recode Depression (k2q32b)Depression =factor(k2q32b, levels =c(2, 1), labels =c("No", "Yes")),# Recode Behavioral Issues (k2q34b)Behavioral_Issues =factor(k2q34b, levels =c(2, 1), labels =c("No", "Yes")) )# Recode education and income categoriesneurodivergent_data <- neurodivergent_data %>%mutate(# Recode education into categorical factorshighgrade_tvis_cat =case_when( higrade_tvis ==1~"Less than high school", higrade_tvis ==2~"High school (including vocational)", higrade_tvis ==3~"Some college or associate degree", higrade_tvis ==4~"College degree or higher",TRUE~NA_character_ ),highgrade_tvis_cat =factor(highgrade_tvis_cat, levels =c("Less than high school", "High school (including vocational)", "Some college or associate degree", "College degree or higher")),# Recode federal poverty level categories into factorsfpl_cat =case_when( fpl %in%c(50:99) | fpl_mean <100~"Less than 100%", fpl %in%c(100:199) | fpl_mean <200~"100% to 199%", fpl %in%c(200:299) | fpl_mean <300~"200% to 299%", fpl %in%c(300:399) | fpl_mean <400~"300% to 399%", fpl %in%c(400:999) | fpl_mean <999~"400% or greater",TRUE~NA_character_ ),fpl_cat =factor(fpl_cat, levels =c("Less than 100%", "100% to 199%", "200% to 299%", "300% to 399%", "400% or greater")) )# Recode sex and race categoriesneurodivergent_data <- neurodivergent_data %>%mutate(# Recode sex into categorical factorssc_sex_cat =case_when( sc_sex ==1~"Male", sc_sex ==2~"Female",TRUE~NA_character_ ),sc_sex_cat =factor(sc_sex_cat, levels =c("Male", "Female")),# Recode race and ethnicityrace =case_when( sc_race_r ==1~"White", sc_race_r ==2~"Black", sc_race_r ==3~"American Indian or Alaska Native", sc_race_r %in%4:5~"Asian, Native Hawaiian, or Pacific Islander", sc_race_r %in%6:7~"Other or mixed race",TRUE~NA_character_ ),ethnicity =case_when( sc_hispanic_r ==1~"Hispanic/Latino", sc_hispanic_r ==2~"Non-Hispanic/Latino",TRUE~NA_character_ ),# Recreate 'sc_race_cat' from race and ethnicity combinationssc_race_cat =case_when( race %in%c("White") & ethnicity =="Non-Hispanic/Latino"~"Non-Hispanic White", race %in%c("Black") & ethnicity =="Non-Hispanic/Latino"~"Non-Hispanic Black or African American", race %in%c("American Indian or Alaska Native") & ethnicity =="Non-Hispanic/Latino"~"Non-Hispanic American Indian or Alaska Native", race %in%c("Asian, Native Hawaiian, or Pacific Islander") & ethnicity =="Non-Hispanic/Latino"~"Non-Hispanic Asian, Native Hawaiian, or Pacific Islander", race %in%c("Other or mixed race") & ethnicity =="Non-Hispanic/Latino"~"Non-Hispanic Other or mixed race", ethnicity =="Hispanic/Latino"~"Hispanic or Latino of any race",TRUE~NA_character_ ),sc_race_cat =factor(sc_race_cat, levels =c("Non-Hispanic White", "Non-Hispanic Black or African American", "Non-Hispanic American Indian or Alaska Native", "Non-Hispanic Asian, Native Hawaiian, or Pacific Islander", "Non-Hispanic Other or mixed race", "Hispanic or Latino of any race")) )
1
ace1 is originally coded by NSCH as a frequency measure, but it’s needed as indicative variable of presence like the other ace# variables.
2
Part of this includes the calculating of the Childhood Flourishing Index (CFI) based on Bethell et al. (2019) criteria
Frequencies & Descriptive Statistics
Expand Code
# Constructing the frequency table for Anxiety, Depression, and Behavioral Issues where the response is "Yes"neurodiv_freq_table <- neurodivergent_data %>% dplyr::summarise(Anxiety_Yes =sum(Anxiety =="Yes", na.rm =TRUE),Depression_Yes =sum(Depression =="Yes", na.rm =TRUE),Behavioral_Issues_Yes =sum(Behavioral_Issues =="Yes", na.rm =TRUE) )# Display table in a simple HTML format using kableneurodiv_freq_table %>% knitr::kable("html", col.names =c("Anxiety", "Depression", "Behavioral Issues"), caption ="Frequency of Mental Health Conditions in Neurodivergent Sample")
Frequency of Mental Health Conditions in Neurodivergent Sample
Anxiety
Depression
Behavioral Issues
13725
6289
13535
Expand Code
# Count the number of subjects with a CFI score of 3 using a logical condition, as this is considered 'Flourishing.'num_subjects_cfi_3 <-sum(neurodivergent_data$CFI ==3, na.rm =TRUE)cat("Number of Subjects Flourishing (CFI Score of 3):", num_subjects_cfi_3, "\n")
Number of Subjects Flourishing (CFI Score of 3): 3265
Expand Code
# Create the summary avg risk 'Y' data frameneurodiv_age_summary <- neurodivergent_data %>% dplyr::summarise(score_mean =mean(sc_age_years, na.rm =TRUE),n =n(), # Sample size for each groupsem =sd(sc_age_years, na.rm =TRUE) /sqrt(n()),.groups ='drop' )# Raincloud plot of ages for neurodivergent participants with colorggplot(neurodivergent_data, aes(x =1, y = sc_age_years)) +# Set x to 1, as there's only one group PupillometryR::geom_flat_violin(adjust =1.5, trim =FALSE, alpha =0.5, color =NA, fill ="deeppink", position =position_nudge(x =0.1, y =0)) +geom_point(alpha =0.1, position =position_jitter(width = .05), size = .10, shape =20, color ="deeppink") +geom_boxplot(outlier.shape =NA, alpha =0, width =0.1, position =position_dodge(width =0.3), colour ="black") +geom_point(data = neurodiv_age_summary, aes(x =1, y = score_mean), shape =18, color ="deeppink", size =3, position =position_nudge(x =0.1)) +geom_errorbar(data = neurodiv_age_summary, aes(x =1, y = score_mean, ymin = score_mean - sem, ymax = score_mean + sem), width =0.05, color ="deeppink", position =position_nudge(x =0.1)) +labs(title ="Age Distribution of Neurodivergent Participants", y ="Age (Years)", x ="") +# No x-axis label since there's only one groupscale_y_continuous(breaks =seq(5, 18, by =1), limits =c(5, 18)) +# Set y-axis range and incrementstheme_minimal() +theme(axis.text.x =element_blank()) # Remove x-axis text
Expand Code
# Bar plot of ACE counts categoriesggplot(neurodivergent_data, aes(x =factor(ace_counts), fill =factor(ace_counts))) +geom_bar(show.legend =FALSE) +geom_text(stat ='count', aes(label = ..count..), position =position_stack(vjust =0.5), color ="white") +labs(x ="ACE Counts", y ="Number of Children", fill ="ACE Counts",title ="Distribution of Children by ACE Counts") +scale_x_discrete(labels =c('0'="0 ACEs", '1'="1 ACE", '2-3'="2-3 ACEs", '4+'="4+ ACEs")) +theme_minimal() +theme(axis.text.x =element_text(angle =0))
Expand Code
# Bar plot of CFI counts categoriesggplot(neurodivergent_data, aes(x =factor(CFI), fill =factor(CFI))) +geom_bar(show.legend =FALSE) +geom_text(stat ='count', aes(label = ..count..), position =position_stack(vjust =0.5), color ="white") +labs(x ="Childhood Flourishing Index (CFI) Score",y ="Number of Children",fill ="CFI Score",title ="Distribution of Children by CFI Score") +theme_minimal() +theme(axis.text.x =element_text(angle =0))
Expand Code
# Bar plot of CFI_dich counts categoriesggplot(neurodivergent_data, aes(x = CFI_dich)) +geom_bar(aes(fill = CFI_dich), show.legend =FALSE) +geom_text(stat ='count', aes(label = ..count..), position =position_stack(vjust =0.5), color ="white") +labs(title ="Distribution of CFI Dichotomous Variable",x ="Child Flourishing Index (Dichotomous)",y ="Count",fill ="CFI") +theme_minimal() +theme(axis.text.x =element_text(angle =0))
Expand Code
# Bar plot for educational attainment counts categoriesggplot(neurodivergent_data %>%filter(!is.na(highgrade_tvis_cat)), aes(x = highgrade_tvis_cat)) +geom_bar(aes(fill = highgrade_tvis_cat), show.legend =FALSE) +geom_text(stat ='count', aes(label = ..count..), position =position_stack(vjust =0.5), color ="white") +labs(title ="Distribution of Adults' Highest Educational Attainment",x ="Educational Attainment",y ="Count",fill ="Educational Attainment") +theme_minimal() +theme(axis.text.x =element_text(angle =45, hjust =1))
Expand Code
# Bar plot for sex counts distributionggplot(neurodivergent_data, aes(x = sc_sex_cat)) +geom_bar(aes(fill = sc_sex_cat), show.legend =FALSE) +geom_text(stat ='count', aes(label = ..count..), position =position_stack(vjust =0.5), color ="white") +scale_fill_manual(values =c("Male"="lightblue", "Female"="pink")) +labs(title ="Distribution of Sex",x ="Sex",y ="Count") +theme_minimal()
Expand Code
#Bar plot for SES counts categoriesggplot(neurodivergent_data, aes(x = fpl_cat)) +geom_bar(aes(fill = fpl_cat), show.legend =FALSE) +geom_text(stat ='count', aes(label = ..count..), position =position_stack(vjust =0.5), color ="white") +labs(title ="Distribution of Socioeconomic Status",x ="Socioeconomic Status",y ="Count") +theme_minimal() +theme(axis.text.x =element_text(angle =45, hjust =1))
Non-Hispanic Asian, Native Hawaiian, or Pacific Islander
+3.499%
-2.070%, +9.068%
0.2
+1.218%
-2.1890%, +4.6259%
0.5
Non-Hispanic Black or African American
-0.780%
-4.571%, +3.010%
0.7
+0.381%
-1.7004%, +2.4631%
0.7
Non-Hispanic Other or mixed race
+0.103%
-3.066%, +3.273%
>0.9
-0.848%
-2.9258%, +1.2294%
0.4
Child Sex
Male
—
—
—
—
Female
+4.743%
+3.087%, +6.399%
<0.001
+2.165%
+0.9965%, +3.3334%
<0.001
1 CI = Confidence Interval
Expand Code
# Plot marginal effects for the Depression modelplot_model(model_dep_mod, type ="int", title ="Interaction: ace_counts * CFI_dich (Depression)")
Expand Code
# Plot marginal effects for the Behavioral Issues modelplot_model(model_beh_mod, type ="int", title ="Interaction: ace_counts * CFI_dich (Behavioral Issues)")
Session Information
To enhance reproducibility, details about the working environment used for these analyses can be found below.